package zjy.android.codeedittext;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.Editable;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * @Create zhang
 * @DATE 2021/10/21 0021
 * @DESC
 */
public class CodeEditText extends androidx.appcompat.widget.AppCompatEditText {

    private Paint shapePaint;
    private int shapeColor = Color.GRAY;
    private int selectShapeColor = Color.BLUE;
    private Path shapePath;

    private Paint textPaint;
    private int textColor;

    private int codeLength;

    private float interval;
    private float shapeWidth;

    private boolean autoSubmit;

    public CodeEditText(@NonNull Context context) {
        super(context);
        init(context, null, 0);
    }

    public CodeEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public CodeEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CodeEditText, defStyleAttr, 0);
        codeLength = typedArray.getInt(R.styleable.CodeEditText_codeLength, 6);
        autoSubmit = typedArray.getBoolean(R.styleable.CodeEditText_autoSubmit, true);
        typedArray.recycle();

        shapePaint = new Paint();
        shapePaint.setColor(shapeColor);
        shapePaint.setStrokeWidth(3);
        shapePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        textPaint = new Paint(getPaint());

        setInputType(EditorInfo.TYPE_CLASS_NUMBER);
        setCursorVisible(false);
        setLongClickable(false);
        setFilters(new InputFilter[]{new InputFilter.LengthFilter(codeLength)});

        setBackgroundColor(Color.TRANSPARENT);
        setPadding(0, 0, 0, 0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        updateShapeConfig();
    }

    /**
     * 更新图形配置
     */
    private void updateShapeConfig() {
        int mw = getMeasuredWidth();
        int ps = getPaddingStart();
        int pe = getPaddingEnd();

        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        shapeWidth = fontMetrics.descent - fontMetrics.ascent;

        interval = (mw - ps - pe - shapeWidth * codeLength) / (codeLength + 1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawShape(canvas);
        drawText(canvas);
    }

    /**
     * 描绘文字
     */
    private void drawText(Canvas canvas) {
        Editable editable = getText();
        if (editable != null) {
            textPaint.setColor(textColor);
            int len = editable.length();
            float height = getHeight();
            Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
            float baseY = (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent;
            for (int i = 0; i < len; i++) {
                float textWidth = textPaint.measureText(editable, i, i + 1);
                float x = interval * (i + 1) + shapeWidth * i + (shapeWidth - textWidth) / 2 + getPaddingStart();
                float y = height / 2 + getPaddingTop() + baseY;
                canvas.drawText(editable, i, i + 1, x, y, textPaint);
            }
        }
    }

    /**
     * 描绘图形
     */
    private void drawShape(Canvas canvas) {
        for (int index = 0; index < codeLength; index++) {
            int color = shapeColor;
            Editable editable = getText();
            if (hasFocus()) {
                if (editable == null && index == 0) {
                    color = selectShapeColor;
                } else if (editable != null && editable.length() == index) {
                    color = selectShapeColor;
                }
            }
            shapePaint.setColor(color);
            float height = getHeight();
            float l, t, r, b;
            l = interval * (index + 1) + shapeWidth * index + getPaddingStart();
            t = (height - shapeWidth) / 2 + getPaddingTop();
            r = l + shapeWidth;
            b = shapeWidth + t;
            RectF rectF = new RectF(l, t, r, b);
            canvas.drawRoundRect(rectF, 20, 20, shapePaint);
//            shapePath.isRect()
//            canvas.drawPath(shapePath, shapePaint);
        }
    }

    /**
     * 设置字体颜色
     * EditText本身颜色设置为透明
     *
     * @see #textPaint
     * @see #textColor
     */
    @Override
    public void setTextColor(ColorStateList colors) {
        if (colors == null) {
            throw new NullPointerException();
        }
        textColor = colors.getColorForState(getDrawableState(), 0);
        super.setTextColor(ColorStateList.valueOf(Color.TRANSPARENT));
    }

    /**
     * 设置字体颜色，
     * EditText本身颜色设置为透明
     *
     * @see #textPaint
     * @see #textColor
     */
    @Override
    public void setTextColor(int color) {
        if (color == textColor) return;
        textColor = color;
        super.setTextColor(Color.TRANSPARENT);
    }

    /**
     * 隐藏光标
     */
    @Override
    public void setCursorVisible(boolean visible) {
        super.setCursorVisible(false);
    }

    /**
     * 禁止长按
     */
    @Override
    public void setLongClickable(boolean longClickable) {
        super.setLongClickable(false);
    }

    /**
     * 判断是否自动提交
     */
    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        if (autoSubmit) {
            onEditorAction(getImeActionId());
        }
    }

    /**
     * 不填满不能提交
     */
    @Override
    public void onEditorAction(int actionCode) {
        Editable editable = getText();
        if (editable == null || editable.length() < codeLength) {
            return;
        }
        super.onEditorAction(actionCode);
    }

    /**
     * 获取文本长度
     */
    private int getTextLength() {
        Editable editable = getText();
        return editable == null ? 0 : editable.length();
    }

    /**
     * 保持光标在最后
     */
    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);
        if (selEnd != selStart || selStart != getTextLength()) {
            setSelection(getTextLength());
        }
    }

    public void setShape(Path path) {
        this.shapePath = path;
        invalidate();
    }

    public static abstract class ShapeAdapter {

    }
}